home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / vidhrdw / irobot.c < prev    next >
C/C++ Source or Header  |  2000-04-23  |  14KB  |  481 lines

  1. /***************************************************************************
  2.  
  3.   vidhrdw.c
  4.  
  5.   Functions to emulate the video hardware of the machine.
  6.  
  7. ***************************************************************************/
  8.  
  9. #include "driver.h"
  10. #include "vidhrdw/generic.h"
  11.  
  12. static struct osd_bitmap *polybitmap1,*polybitmap2;
  13. static struct osd_bitmap *polybitmap;
  14.  
  15. extern UINT8 irvg_clear;
  16. extern UINT8 irobot_bufsel;
  17. extern UINT8 irobot_alphamap;
  18. extern UINT8 *irobot_combase;
  19.  
  20. static int ir_xmin, ir_ymin, ir_xmax, ir_ymax; /* clipping area */
  21.  
  22.  
  23.  
  24. /***************************************************************************
  25.  
  26.   Convert the color PROMs into a more useable format.
  27.  
  28.   5 bits from polygon ram address the palette ram
  29.  
  30.   Output of color RAM
  31.   bit 8 -- inverter -- 1K ohm resistor  -- RED
  32.   bit 7 -- inverter -- 2.2K ohm resistor  -- RED
  33.         -- inverter -- 1K ohm resistor  -- GREEN
  34.         -- inverter -- 2.2K ohm resistor  -- GREEN
  35.         -- inverter -- 1K ohm resistor  -- BLUE
  36.         -- inverter -- 2.2K ohm resistor  -- BLUE
  37.         -- inverter -- 2.2K ohm resistor  -- INT
  38.         -- inverter -- 4.7K ohm resistor  -- INT
  39.   bit 0 -- inverter -- 9.1K ohm resistor  -- INT
  40.  
  41.   Alphanumeric colors are generated by ROM .125, it's outputs are connected
  42.   to bits 1..8 as above. The inputs are:
  43.  
  44.   A0..1 - Character color
  45.   A2    - Character image (1=pixel on/0=off)
  46.   A3..4 - Alphamap 0,1 (appears that only Alphamap1 is used, it is set by
  47.           the processor)
  48.  
  49. ***************************************************************************/
  50. void irobot_vh_convert_color_prom(unsigned char *palette, unsigned short *colortable,const unsigned char *color_prom)
  51. {
  52.     int i;
  53.     #define TOTAL_COLORS(gfxn) (Machine->gfx[gfxn]->total_colors * Machine->gfx[gfxn]->color_granularity)
  54.     #define COLOR(gfxn,offs) (colortable[Machine->drv->gfxdecodeinfo[gfxn].color_codes_start + offs])
  55.  
  56.     /* the palette will be initialized by the game. We just set it to some */
  57.     /* pre-cooked values so the startup copyright notice can be displayed. */
  58.     for (i = 0;i < 64;i++)
  59.     {
  60.         *(palette++) = ((i & 1) >> 0) * 0xff;
  61.         *(palette++) = ((i & 2) >> 1) * 0xff;
  62.         *(palette++) = ((i & 4) >> 2) * 0xff;
  63.     }
  64.  
  65.     /* Convert the color prom for the text palette */
  66.     for (i = 0;i < 32;i++)
  67.     {
  68.         int r,g,b;
  69.         int bits,intensity;
  70.         unsigned int color;
  71.  
  72.         color = *color_prom;
  73.         intensity = color & 0x03;
  74.         bits = (color >> 6) & 0x03;
  75.         r = 16 * bits * intensity;
  76.         bits = (color >> 4) & 0x03;
  77.         g = 16 * bits * intensity;
  78.         bits = (color >> 2) & 0x03;
  79.         b = 16 * bits * intensity;
  80.         *(palette++) = r;
  81.         *(palette++) = g;
  82.         *(palette++) = b;
  83.         color_prom++;
  84.     }
  85.  
  86.     /* polygons */
  87.     for (i = 0;i < 64;i++)
  88.          colortable[i] = i;
  89.  
  90.     /* text */
  91.     for (i = 0;i < TOTAL_COLORS(0);i++)
  92.     {
  93.         COLOR(0,i) = ((i & 0x18) | ((i & 0x01) << 2) | ((i & 0x06) >> 1)) + 64;
  94.     }
  95. }
  96.  
  97.  
  98. WRITE_HANDLER( irobot_paletteram_w )
  99. {
  100.     int r,g,b;
  101.     int bits,intensity;
  102.     unsigned int color;
  103.  
  104.     color = ((data << 1) | (offset & 0x01)) ^ 0x1ff;
  105.     intensity = color & 0x07;
  106.     bits = (color >> 3) & 0x03;
  107.     b = 8 * bits * intensity;
  108.     bits = (color >> 5) & 0x03;
  109.     g = 8 * bits * intensity;
  110.     bits = (color >> 7) & 0x03;
  111.     r = 8 * bits * intensity;
  112.     palette_change_color((offset >> 1) & 0x3F,r,g,b);
  113. }
  114.  
  115.  
  116. /***************************************************************************
  117.  
  118.   Fast line drawing.
  119.  
  120. ***************************************************************************/
  121. #define DRAW_HLINE_FUNC(NAME, TYPE, XSTART, YSTART, XADV)                 \
  122.     static void NAME(int x1, int x2, int y, int col)                    \
  123.     {                                                                    \
  124.         TYPE *dest = &((TYPE *)polybitmap->line[YSTART])[XSTART];        \
  125.         int dx = XADV;                                                    \
  126.         for ( ; x1 <= x2; x1++, dest += dx)                                \
  127.             *dest = col;                                                \
  128.     }
  129.  
  130. DRAW_HLINE_FUNC(draw_hline_8, UINT8, x1, y, 1)
  131. DRAW_HLINE_FUNC(draw_hline_8_fx, UINT8, ir_xmax - x1, y, -1)
  132. DRAW_HLINE_FUNC(draw_hline_8_fy, UINT8, x1, ir_ymax - y, 1)
  133. DRAW_HLINE_FUNC(draw_hline_8_fx_fy, UINT8, ir_xmax - x1, ir_ymax - y, -1)
  134.  
  135. DRAW_HLINE_FUNC(draw_hline_8_swap, UINT8, y, x1, polybitmap->line[1] - polybitmap->line[0])
  136. DRAW_HLINE_FUNC(draw_hline_8_swap_fx, UINT8, ir_ymax - y, x1, polybitmap->line[1] - polybitmap->line[0])
  137. DRAW_HLINE_FUNC(draw_hline_8_swap_fy, UINT8, y, ir_xmax - x1, polybitmap->line[0] - polybitmap->line[1])
  138. DRAW_HLINE_FUNC(draw_hline_8_swap_fx_fy, UINT8, ir_ymax - y, ir_xmax - x1, polybitmap->line[0] - polybitmap->line[1])
  139.  
  140. DRAW_HLINE_FUNC(draw_hline_16, UINT16, x1, y, 1)
  141. DRAW_HLINE_FUNC(draw_hline_16_fx, UINT16, ir_xmax - x1, y, -1)
  142. DRAW_HLINE_FUNC(draw_hline_16_fy, UINT16, x1, ir_ymax - y, 1)
  143. DRAW_HLINE_FUNC(draw_hline_16_fx_fy, UINT16, ir_xmax - x1, ir_ymax - y, -1)
  144.  
  145. DRAW_HLINE_FUNC(draw_hline_16_swap, UINT16, y, x1, (polybitmap->line[1] - polybitmap->line[0]) / 2)
  146. DRAW_HLINE_FUNC(draw_hline_16_swap_fx, UINT16, ir_ymax - y, x1, (polybitmap->line[1] - polybitmap->line[0]) / 2)
  147. DRAW_HLINE_FUNC(draw_hline_16_swap_fy, UINT16, y, ir_xmax - x1, (polybitmap->line[0] - polybitmap->line[1]) / 2)
  148. DRAW_HLINE_FUNC(draw_hline_16_swap_fx_fy, UINT16, ir_ymax - y, ir_xmax - x1, (polybitmap->line[0] - polybitmap->line[1]) / 2)
  149.  
  150. static void (*draw_hline)(int x1, int x2, int y, int col);
  151.  
  152. static void (*hline_8_table[8])(int x1, int x2, int y, int col) =
  153. {
  154.     draw_hline_8, draw_hline_8_fx, draw_hline_8_fy, draw_hline_8_fx_fy,
  155.     draw_hline_8_swap, draw_hline_8_swap_fx, draw_hline_8_swap_fy, draw_hline_8_swap_fx_fy
  156. };
  157.  
  158. static void (*hline_16_table[8])(int x1, int x2, int y, int col) =
  159. {
  160.     draw_hline_16, draw_hline_16_fx, draw_hline_16_fy, draw_hline_16_fx_fy,
  161.     draw_hline_16_swap, draw_hline_16_swap_fx, draw_hline_16_swap_fy, draw_hline_16_swap_fx_fy
  162. };
  163.  
  164. /***************************************************************************
  165.  
  166.   Start the video hardware emulation.
  167.  
  168. ***************************************************************************/
  169. int irobot_vh_start(void)
  170. {
  171.     /* Setup 2 bitmaps for the polygon generator */
  172.     if ((polybitmap1 = osd_create_bitmap(Machine->drv->screen_width,Machine->drv->screen_height)) == 0)
  173.         return 1;
  174.     if ((polybitmap2 = osd_create_bitmap(Machine->drv->screen_width,Machine->drv->screen_height)) == 0)
  175.         return 1;
  176.  
  177.     /* Set clipping */
  178.     ir_xmin = ir_ymin = 0;
  179.     ir_xmax = Machine->drv->screen_width;
  180.     ir_ymax = Machine->drv->screen_height;
  181.  
  182.     /* Compute orientation parameters */
  183.     if (polybitmap1->depth == 8)
  184.         draw_hline = hline_8_table[Machine->orientation & ORIENTATION_MASK];
  185.     else
  186.         draw_hline = hline_16_table[Machine->orientation & ORIENTATION_MASK];
  187.  
  188.     return 0;
  189. }
  190.  
  191. /***************************************************************************
  192.  
  193.   Stop the video hardware emulation.
  194.  
  195. ***************************************************************************/
  196. void irobot_vh_stop(void)
  197. {
  198.     osd_free_bitmap(polybitmap1);
  199.     osd_free_bitmap(polybitmap2);
  200. }
  201.  
  202. /***************************************************************************
  203.  
  204.     Polygon Generator  (Preliminary information)
  205.     The polygon communication ram works as follows (each location is a 16-bit word):
  206.  
  207.     0000-xxxx: Object pointer table
  208.         bits 00..10: Address of object data
  209.         bits 12..15: Object type
  210.             0x4 = Polygon
  211.             0x8 = Point
  212.             0xC = Vector
  213.         (0xFFFF means end of table)
  214.  
  215.     Point Object:
  216.         Word 0, bits 0..15: X Position  (0xFFFF = end of point objects)
  217.         Word 1, bits 7..15: Y Position
  218.         bits 0..5: Color
  219.  
  220.     Vector Object:
  221.         Word 0, bits 7..15: Ending Y   (0xFFFF = end of line objects)
  222.         Word 1, bits 7..15: Starting Y
  223.                 bits 0..5: Color
  224.         Word 2: Slope
  225.         Word 3, bits 0..15: Starting X
  226.  
  227.     Polygon Object:
  228.         Word 0, bits 0..10: Pointer to second slope list
  229.         Word 1, bits 0..15: Starting X first vector
  230.         Word 2, bits 0..15: Starting X second vector
  231.         Word 3, bits 0..5: Color
  232.         bits 7..15: Initial Y value
  233.  
  234.     Slope Lists: (one starts at Word 4, other starts at pointer in Word 0)
  235.         Word 0, Slope (0xFFFF = side done)
  236.         Word 1, bits 7..15: Ending Y of vector
  237.  
  238.     Each side is a continous set of vectors. Both sides are drawn at
  239.     the same time and the space between them is filled in.
  240.  
  241. ***************************************************************************/
  242.  
  243. void irobot_poly_clear(void) {
  244.  
  245.     if (irobot_bufsel)
  246.         osd_clearbitmap(polybitmap2);
  247.     else
  248.         osd_clearbitmap(polybitmap1);
  249. }
  250.  
  251. INLINE void irobot_draw_pixel (int x, int y, int col)
  252. {
  253.     if (x < ir_xmin || x >= ir_xmax)
  254.         return;
  255.     if (y < ir_ymin || y >= ir_ymax)
  256.         return;
  257.  
  258.     plot_pixel (polybitmap, x, y, col);
  259. }
  260.  
  261. /*
  262.      Line draw routine
  263.      modified from a routine written by Andrew Caldwell
  264.  */
  265.  
  266. void irobot_draw_line (int x1, int y1, int x2, int y2, int col)
  267. {
  268.     int dx,dy,sx,sy,cx,cy;
  269.  
  270.     dx = abs(x1-x2);
  271.     dy = abs(y1-y2);
  272.     sx = (x1 <= x2) ? 1: -1;
  273.     sy = (y1 <= y2) ? 1: -1;
  274.     cx = dx/2;
  275.     cy = dy/2;
  276.  
  277.     if (dx>=dy)
  278.     {
  279.         for (;;)
  280.         {
  281.              irobot_draw_pixel (x1, y1, col);
  282.              if (x1 == x2) break;
  283.              x1 += sx;
  284.              cx -= dy;
  285.              if (cx < 0)
  286.              {
  287.                   y1 += sy;
  288.                   cx += dx;
  289.              }
  290.         }
  291.     }
  292.     else
  293.     {
  294.         for (;;)
  295.         {
  296.             irobot_draw_pixel (x1, y1, col);
  297.             if (y1 == y2) break;
  298.             y1 += sy;
  299.             cy -= dx;
  300.             if (cy < 0)
  301.             {
  302.                  x1 += sx;
  303.                  cy += dy;
  304.              }
  305.         }
  306.     }
  307. }
  308.  
  309.  
  310. #define ROUND_TO_PIXEL(x)    (((x) >> 7) - 128)
  311.  
  312. void run_video(void)
  313. {
  314.     int sx,sy,ex,ey,sx2,ey2;
  315.     int color;
  316.     unsigned int d1;
  317.     int lpnt,spnt,spnt2;
  318.     int shp;
  319.     INT32 word1,word2;
  320.  
  321.     logerror("Starting Polygon Generator, Clear=%d\n",irvg_clear);
  322.  
  323.     if (irobot_bufsel)
  324.         polybitmap = polybitmap2;
  325.     else
  326.         polybitmap = polybitmap1;
  327.  
  328.     //    if (irvg_clear) irobot_poly_clear();
  329.     lpnt=0;
  330.     while (lpnt < 0xFFF)
  331.     {
  332.         d1 = READ_WORD(&irobot_combase[lpnt]);
  333.         lpnt+=2;
  334.         if (d1 == 0xFFFF) break;
  335.         spnt = (d1 & 0x07FF) << 1;
  336.         shp = (d1 & 0xF000) >> 12;
  337.  
  338.         /* Pixel */
  339.         if (shp == 0x8)
  340.         {
  341.             while (spnt < 0xFFE)
  342.             {
  343.                 sx = READ_WORD(&irobot_combase[spnt]);
  344.                 if (sx == 0xFFFF) break;
  345.                 sy = READ_WORD(&irobot_combase[spnt+2]);
  346.                 color = Machine->pens[sy & 0x3F];
  347.                 irobot_draw_pixel(ROUND_TO_PIXEL(sx),ROUND_TO_PIXEL(sy),color);
  348.                 spnt+=4;
  349.             }//while object
  350.         }//if point
  351.  
  352.         /* Line */
  353.         if (shp == 0xC)
  354.         {
  355.             while (spnt < 0xFFF)
  356.             {
  357.                 ey = READ_WORD(&irobot_combase[spnt]);
  358.                 if (ey == 0xFFFF) break;
  359.                 ey = ROUND_TO_PIXEL(ey);
  360.                 sy = READ_WORD(&irobot_combase[spnt+2]);
  361.                 color = Machine->pens[sy & 0x3F];
  362.                 sy = ROUND_TO_PIXEL(sy);
  363.                 sx = READ_WORD(&irobot_combase[spnt+6]);
  364.                 word1 = (INT16)READ_WORD(&irobot_combase[spnt+4]);
  365.                 ex = sx + word1 * (ey - sy + 1);
  366.                 irobot_draw_line(ROUND_TO_PIXEL(sx),sy,ROUND_TO_PIXEL(ex),ey,color);
  367.                 spnt+=8;
  368.             }//while object
  369.         }//if line
  370.  
  371.         /* Polygon */
  372.         if (shp == 0x4)
  373.         {
  374.             spnt2 = READ_WORD(&irobot_combase[spnt]);
  375.             spnt2 = (spnt2 & 0x7FF) << 1;
  376.  
  377.             sx = READ_WORD(&irobot_combase[spnt+2]);
  378.             sx2 = READ_WORD(&irobot_combase[spnt+4]);
  379.             sy = READ_WORD(&irobot_combase[spnt+6]);
  380.             color = Machine->pens[sy & 0x3F];
  381.             sy = ROUND_TO_PIXEL(sy);
  382.             spnt+=8;
  383.  
  384.             word1 = (INT16)READ_WORD(&irobot_combase[spnt]);
  385.             ey = READ_WORD(&irobot_combase[spnt+2]);
  386.             if (word1 != -1 || ey != 0xFFFF)
  387.             {
  388.                 ey = ROUND_TO_PIXEL(ey);
  389.                 spnt+=4;
  390.  
  391.                 sx += word1;
  392.  
  393.                 word2 = (INT16)READ_WORD(&irobot_combase[spnt2]);
  394.                 ey2 = ROUND_TO_PIXEL(READ_WORD(&irobot_combase[spnt2+2]));
  395.                 spnt2+=4;
  396.  
  397.                 sx2 += word2;
  398.  
  399.                 while(1)
  400.                 {
  401.                     if (sy >= ir_ymin && sy < ir_ymax)
  402.                     {
  403.                         int x1 = ROUND_TO_PIXEL(sx);
  404.                         int x2 = ROUND_TO_PIXEL(sx2);
  405.                         int temp;
  406.  
  407.                         if (x1 > x2) temp = x1, x1 = x2, x2 = temp;
  408.                         if (x1 < ir_xmin) x1 = ir_xmin;
  409.                         if (x2 > ir_xmax) x2 = ir_xmax;
  410.                         if (x1 <= x2)
  411.                             (*draw_hline)(x1, x2, sy, color);
  412.                     }
  413.  
  414.                     sy++;
  415.  
  416.                     if (sy >= ey)
  417.                     {
  418.                         word1 = (INT16)READ_WORD(&irobot_combase[spnt]);
  419.                         ey = READ_WORD(&irobot_combase[spnt+2]);
  420.                         if (word1 == -1 && ey == 0xFFFF)
  421.                             break;
  422.                         ey = ROUND_TO_PIXEL(ey);
  423.                         spnt+=4;
  424.                     }
  425.                     else
  426.                         sx += word1;
  427.  
  428.                     if (sy >= ey2)
  429.                     {
  430.                         word2 = (INT16)READ_WORD(&irobot_combase[spnt2]);
  431.                         ey2 = ROUND_TO_PIXEL(READ_WORD(&irobot_combase[spnt2+2]));
  432.                         spnt2+=4;
  433.                     }
  434.                     else
  435.                         sx2 += word2;
  436.  
  437.                 } //while polygon
  438.             }//if at least 2 sides
  439.         } //if polygon
  440.     } //while object
  441. }
  442.  
  443.  
  444.  
  445. /***************************************************************************
  446.  
  447.   Draw the game screen in the given osd_bitmap.
  448.   Do NOT call osd_update_display() from this function, it will be called by
  449.   the main emulation engine.
  450.  
  451. ***************************************************************************/
  452. void irobot_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
  453. {
  454.     int x, y, offs;
  455.  
  456.     logerror("Screen Refresh\n");
  457.  
  458.     palette_recalc();
  459.  
  460.     /* copy the polygon bitmap */
  461.     if (irobot_bufsel)
  462.         copybitmap(bitmap,polybitmap1,0,0,0,0,&Machine->drv->visible_area,TRANSPARENCY_NONE,0);
  463.     else
  464.         copybitmap(bitmap,polybitmap2,0,0,0,0,&Machine->drv->visible_area,TRANSPARENCY_NONE,0);
  465.  
  466.     /* redraw the non-zero characters in the alpha layer */
  467.     for (y = offs = 0; y < 32; y++)
  468.         for (x = 0; x < 32; x++, offs++)
  469.             if (videoram[offs] != 0)
  470.             {
  471.                 int code = videoram[offs] & 0x3f;
  472.                 int color = ((videoram[offs] & 0xC0) >> 6) | (irobot_alphamap >> 3);
  473.  
  474.                 drawgfx(bitmap,Machine->gfx[0],
  475.                         code, color,
  476.                         0,0,
  477.                         8*x,8*y,
  478.                         &Machine->drv->visible_area,TRANSPARENCY_COLOR,64);
  479.             }
  480. }
  481.